<?php
namespace lib;

set_time_limit(0);
ignore_user_abort(true);

class Qq{

    protected $conf;
    protected $request;
    protected static $activeGroupMap = [];

    function __construct(){
        $this->request = new \lib\Request();
    }

    function start(){
        $this->conf = Cache::get('conf');
        $data = [
            'ptwebqq'   => '',
            'clientid'  => '53999199',
            'psessionid'    => $this->conf['login2']['psessionid'],
            'key'   => ''
        ];
        try{
	        while(true){
		        $this->poll($data);
                $this->task();
	        }
        }catch (\Exception $e){
        	$this->log($e, 'systemErr');
        }
    }

    //todo::多线程，更多api,队列
    function poll($data){
        $msg = $this->request
            ->url('https://d1.web2.qq.com/channel/poll2')
            ->setReferer('https://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2')
            ->setHeader(['origin: https://d1.web2.qq.com'])
            ->setData(['r'=>json_encode($data)])
            ->setMethod('post')
            ->autoCookie()
            ->setReuse()
            ->send();
        $msg = json_decode($msg, true);
        $this->responseCheck($msg, $msg, __METHOD__);
	    if(isset($msg['result'])){      //有新消息
		    $this->explainMsg($msg);
	    }
    }

    function explainMsg($msg){
        foreach ($msg['result'] as $msgItem){
            $value = $msgItem['value'];
            if('group_message' == $msg['result'][0]['poll_type'] && $value['send_uin'] != $this->conf['login2']['uin']){      //如果是群消息
                $uin = $value['from_uin'];
                $content = $value['content'];
                $help = "\n输入'指令'获取功能菜单..";
                switch (trim($content[1])){
                    case '希图斯':
                        $cetus = Cache::get('cetus');
                        if(!$cetus){
                            $res = $this->request->url('https://api.warframestat.us/pc/cetusCycle')->send();
                            $cetus = json_decode($res, true);
                            $cetus['update'] = date('Y-m-d H:i:s');
                            Cache::set('cetus', $cetus, 60);
                        }
                        $time = str_replace(['h', 'm', 's', ' '], ['小时', '分', '秒', ''], $cetus['timeLeft']);
                        $toDate = $cetus['isDay'] ? '夜晚' : '白天';
                        $date = $cetus['isDay'] ? '白天' : '夜晚';
                        $msg = '希图斯 现在是：' . $date;
                        $msg .= "\n{$time}后，进入" . $toDate;
                        $msg .= "\n更新于：" . $cetus['update'];
                        $this->sendMsg($uin, $msg);
                        break;
                    case '地球':
                        $earth = Cache::get('earth');
                        if(!$earth){
                            $res = $this->request->url('https://api.warframestat.us/pc/earthCycle')->send();
                            $earth = json_decode($res, true);
                            $earth['update'] = date('Y-m-d H:i:s');
                            Cache::set('earth', $earth, 60);
                        }
                        $time = str_replace(['h', 'm', 's', ' '], ['小时', '分', '秒', ''], $earth['timeLeft']);
                        $toDate = $earth['isDay'] ? '夜晚' : '白天';
                        $date = $earth['isDay'] ? '白天' : '夜晚';
                        $msg = '地球 现在是：' . $date;
                        $msg .= "\n{$time}后，进入" . $toDate;
                        $msg .= "\n更新于：" . $earth['update'];
                        $this->sendMsg($uin, $msg);
                        break;
                    case '警报':
                        $data = Wf::buildAlert();
                        $length = ceil(count($data) / 3);
                        for ($i = 0; $i < $length; $i ++){
                            $cache = array_splice($data, 0, 3);
                            $msg = implode("\n--------------------\n", $cache);
                            if($i == $length - 1){
                                $msg .= $help;
                            }
                            $this->sendMsg($uin, $msg);
                        }
                        break;
                    case '入侵':
                        $this->sendMsg($uin, '还没开发出来...' . $help);
                        break;
                    case '突击':
                        $msg = Wf::buildSortie();
                        $this->sendMsg($uin, $msg);
                        break;
                    case '裂缝':
                        $this->sendMsg($uin,  '还没开发出来...' . $help);
                        break;
                    case '指令':
                        $retMsg = "希图斯|地球|警报|入侵|突击|裂缝|版本\n[购买 腐蚀投射]-按白金从低到高\n[出售 绝路p]-按白金从高到低";
                        $retMsg && $this->sendMsg($uin, $retMsg);
                        break;
                    case '版本':
                        $retMsg = "v1.0 release\n字典鸣谢：云之幻";
                        $retMsg .= $help;
                        $retMsg && $this->sendMsg($uin, $retMsg);
                        break;
                    default:
                        $searchType = 'buy';
                        preg_match('/^购买\s(.*)/', $content[1], $search);
                        if(!$search){
                            $searchType = 'sell';
                            preg_match('/^出售\s(.*)/', $content[1], $search);
                        }
                        if($search){
                            $keywords = Wf::explain($search[1], 'sale');
                            if($keywords){
                                $data = [];
                                $message = [];
                                $action = 'buy' == $searchType ? '出售' : '求购';
                                $this->sendMsg($uin, "开始查询【{$keywords['Zh']}】{$action}信息");
                                $res = $this->request
                                    ->url("https://api.warframe.market/v1/items/{$keywords['Search']}/orders")
                                    ->send();
                                $res = json_decode($res, true);
                                $orders = $res['payload']['orders'];
                                $orderType = 'buy' == $searchType ? 'sell' : 'buy';
                                foreach ($orders as $item){
                                    if($item['order_type'] == $orderType && $item['user']['status'] != 'offline'){
                                        array_push($data, $item);
                                    }
                                }
                                $sortType = 'buy' == $searchType ? SORT_ASC : SORT_DESC;
                                array_multisort(array_column($data, 'platinum'), $sortType, $data);
                                if(empty($data)){
                                    $this->sendMsg($uin, '暂无数据!' . $help);
                                    return;
                                }
                                $list = array_splice($data, 0, 4);
                                foreach ($list as $key => $item){
                                    $msg = 0 == $key ? "#【{$keywords['Zh']}】{$action}信息\n" : '';
                                    $status = $item['user']['status'] == 'ingame' ? '游戏中' : '在线';
                                    $msg .= "{$item['user']['ingame_name']}|{$status}|{$item['platinum']}白金|数量{$item['quantity']}";
                                    if('buy' == $searchType){
                                        $msg .= "\n*\n/w {$item['user']['ingame_name']} Hi! I want 2 buy: {$keywords['En']} for {$item['platinum']} platinum.";
                                    }else{
                                        $msg .= "\n*\n/w {$item['user']['ingame_name']} Hi! I want 2 sell: {$keywords['En']} for {$item['platinum']} platinum.";
                                    }
                                    array_push($message, $msg);
                                }
                                array_push($message, $help);
                                $this->sendMsg($uin, implode("\n----------\n", $message));

                            }else{
                                $this->sendMsg($uin, '没有找到该条目!' . $help);
                            }
                        }
                        break;
                }
            }
        }
    }

    function sendMsg($uin, $msg, $level = 0){
        //写入活动的群组uin，用于推送消息
        if(!in_array($uin, self::$activeGroupMap)){
            array_push(self::$activeGroupMap, $uin);
        }
        $sendData = json_encode([
            'group_uin' => $uin,
            'content'   => json_encode([
                $msg,
                [
                    'font',
                    [
                        'name' => '宋体',
                        'size' => 10,
                        'style' => [0, 0, 0],
                        'color' => '000000'
                    ]
                ]
            ], JSON_UNESCAPED_UNICODE),
            'face'  => 0,
            'clientid'  => 53999199,
            'msg_id'    => $this->generateMsgId(),
            'psessionid'    => $this->conf['login2']['psessionid']
        ], JSON_UNESCAPED_UNICODE);
        $response = $this->request
            ->url('https://d1.web2.qq.com/channel/send_qun_msg2')
            ->setReferer('https://d1.web2.qq.com/cfproxy.html?v=20151105001&callback=1')
            ->setHeader(['origin: https://d1.web2.qq.com'])
            ->setData(['r'=>$sendData])
            ->setMethod('post')
            ->autoCookie()
            ->send();
	    $response = json_decode($response, true);
	    $this->responseCheck($response, $sendData, __METHOD__);
//	    if(0 != $response['retcode'] && $level < 2){      //如果发送失败，尝试再发一次
//		    $level ++;
//		    $this->sendMsg($uin, $msg, $level);
//	    }
    }

    function generateMsgId($length = 8){
        $code = '';
        $chars = '0123456789';
        while (strlen($code) < $length) {
            $value = $chars[mt_rand(0, strlen($chars) - 1)];
            if(0 == $value){
                continue;
            }
            $code .= $value;
        }
        return (int)$code;
    }

    //废弃接口
    function sendPicture($uin, $pic){

    	$samp = mt_rand(1000, 9999);
	    $myUin = $this->conf['login2']['uin'];
	    $url = "https://file1.web.qq.com/v2/{$myUin}/{$uin}/{$samp}/1075/47450/1/f/1/0/0?psessionid={$this->conf['login2']['psessionid']}";
	    $this->request
		    ->url($url)
		    ->attache($pic)
		    ->setReferer('http://web2.qq.com/domain.html')
		    ->setMethod('post')
		    ->autoCookie()
		    ->send();
    }

    function task($level = 0){
    	$alertStamp = Cache::get('alert_task');
        $sortieStamp = Cache::get('sortie_task');
        $invasionsStamp = Cache::get('invasions_task');
        if(!$alertStamp){
            $res = $this->request->url('https://api.warframestat.us/pc/alerts')->send();
            $data = json_decode($res, true);
            $lastData = null;
            if($data){
                $lastData = Cache::get('alert_data');
                Cache::set('alert_data', $data);
            }else{
                if($level < 3){
                    $level ++;
                    $this->task($level);
                }else{
                    return;
                }
            }
            if($lastData){
                $alerts = [];
                foreach ($data as $item){
                    $isset = false;
                    foreach ($lastData as $val){
                        if($item['id'] == $val['id']){
                            $isset = true;
                            continue;
                        }
                    }
                    if(false == $isset){
                        if($item['mission']['reward']['items']){
                            array_push($alerts, $item);
                        }
                    }
                }
                if($alerts){
                    $message = Wf::buildAlert($alerts);
                    $message = implode("\n--------------------\n", $message);
                    $msg = '#Teeno，有' . count($alerts) . "条新警报\n" . $message;
                    $msg .= "\n输入'指令'获取功能菜单..";
                    foreach (self::$activeGroupMap as $item){
                        $this->sendMsg($item, $msg);
                    }
                }
                Cache::set('alert_task', true, 60);
            }
        }
        if(!$sortieStamp){
            $res = $this->request->url('https://api.warframestat.us/pc/sortie')->send();
            $data = json_decode($res, true);
            $expiry = strtotime($data['expiry']) - time() + 3;
            Cache::set('sortie_task', $expiry);
            Cache::set('sortie_data', $data);
        }
    }

    function responseCheck($response, $params, $action){
    	if($response['retcode'] != 0){
            switch ($response['retcode']){
                //需刷新登陆状态
                case 103:
                    $onlineUrl = 'https://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq='.$this->conf['vf']['vfwebqq'].'&clientid=53999199&psessionid='.$this->conf['login2']['psessionid'].'&t=' . Encoder::times();
                    $online = $this->request
                        ->url($onlineUrl)
                        ->setReferer('https://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2')
                        ->autoCookie()
                        ->send();
                    $this->log($online, 'resetOnline');
                    break;
            }
		    $this->log([$params, $response], $action . 'Err');
	    }
    }

    function log($content, $type){
        $filename = date('YmdH');
        $log = "\n============={$type}=============\n";
        $log .= is_string($content) ? $content : var_export($content, true);
        $log .= "\n" . date('Y-m-d H:i:s');
        file_put_contents(ROOT_PATH . "log/{$filename}.txt", $log, FILE_APPEND);
    }

}